﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Web;
using vudu.Logica.Clases;
using vudu.ClasesDominio;

namespace vudu.Datos.SqlServer
{
    public class SqlServerMateria
    {
        Conexion conex = new Conexion();


        #region Metodos Definitivos

        #region Agregar Materia
        public int AgregarMateria(Materia materia, int idEscuela)
        {
            List<String> variables = new List<String>();
            List<String> valores = new List<String>();
            variables.Add("nombre_materia");
            variables.Add("descripcion_materia");
            variables.Add("horas_teoria");
            variables.Add("horas_practica");
            variables.Add("estatus_materia");
            variables.Add("unidades_credito");
            variables.Add("id_Escuela");
            valores.Add(materia.Nombre);
            valores.Add(materia.Descripcion);
            valores.Add(materia.HorasTeoria.ToString());
            valores.Add(materia.HorasPractica.ToString());
            valores.Add(materia.Estatus);
            valores.Add(materia.NumeroCreditos.ToString());
            valores.Add(idEscuela.ToString());
            Conexion conexion = new Conexion();

            int resultado = EjecutarQuery(conexion, "[dbo].[AgregarMateria]", variables, valores);

            conexion.CerrarConexionBd();

            return resultado;

        }

        #endregion Agregar Materia

        #region Editar Materia

        public int EditarMateria(Materia materia)
        {
            List<String> variables = new List<String>();
            List<String> valores = new List<String>();
            variables.Add("nombre_materia");
            variables.Add("descripcion_materia");
            variables.Add("horas_teoria");
            variables.Add("horas_practica");
            variables.Add("estatus_materia");
            variables.Add("unidades_credito");
            variables.Add("id_Materia");
            valores.Add(materia.Nombre);
            valores.Add(materia.Descripcion);
            valores.Add(materia.HorasTeoria.ToString());
            valores.Add(materia.HorasPractica.ToString());
            valores.Add(materia.Estatus);
            valores.Add(materia.NumeroCreditos.ToString());
            valores.Add(materia.Codigo.ToString());
            Conexion conexion = new Conexion();

            int resultado = EjecutarQuery(conexion, "[dbo].[EditarMateria]", variables, valores);

            conexion.CerrarConexionBd();

            return resultado;

        }

        #endregion Editar Materia

        #region Eliminar Materia

        public int EliminarMateria(int idMateria)
        {
            List<String> variables = new List<String>();
            List<String> valores = new List<String>();
            variables.Add("id_Materia");
            valores.Add(idMateria.ToString());
            Conexion conexion = new Conexion();

            int resultado = EjecutarQuery(conexion, "[dbo].[EliminarMateria]", variables, valores);

            conexion.CerrarConexionBd();

            return resultado;

        }

        #endregion Eliminar Materia

        #region Consultar Materias Escuela

        public List<Materia> ConsultarMateriasEscuela(int idEscuela)
        {
            List<String> variables = new List<String>();
            List<String> valores = new List<String>();
            List<Materia> resultado = new List<Materia>();
            variables.Add("id_Escuela");
            valores.Add(idEscuela.ToString());
            Conexion conexion = new Conexion();

            SqlDataReader reader = BuscarData(conexion, "[dbo].[ConsultarMateriasEscuela]", variables, valores);


            while (reader.Read())
            {

                Materia materia = new Materia(reader.GetInt32(0), reader.GetString(1), reader.GetInt32(3), reader.GetInt32(4), reader.GetString(2), reader.GetString(5), reader.GetInt32(6), 0);
                resultado.Add(materia);


            }
            conexion.CerrarConexionBd();

            return resultado;

        }

        #endregion Consultar Materias Escuela



        #region Buscar Data

        /// <summary>
        /// Metodo que recibe se encargar de invocar a los stored
        /// procedures y devolver el sqlreader a los metodos
        /// de donde es invocado.
        /// </summary>>

        public SqlDataReader BuscarData(Conexion conexion, String nombreProcedure, List<String> variablesProcedure, List<String> valoresVariables)
        {


            SqlCommand comando = new SqlCommand();
            SqlDataReader lector = null;

            try
            {
                //se abre una conexion a base de datos
                conexion.AbrirConexionBd();
                //se completa el objeto comando, con la informacion de la conexion , variables, y nombre del stored procedure
                comando.Connection = conexion.ObjetoConexion();
                comando.CommandType = System.Data.CommandType.StoredProcedure;
                comando.CommandText = nombreProcedure;
                comando.CommandTimeout = 10;
                //variables del stored procedure de sql server
                int i = 0;
                while (i < variablesProcedure.Count())
                {

                    comando.Parameters.AddWithValue(variablesProcedure.ElementAt(i), valoresVariables.ElementAt(i));
                    comando.Parameters[variablesProcedure.ElementAt(i)].Direction = ParameterDirection.Input;

                    i++;
                }
                //se ejecuta el comando
                lector = comando.ExecuteReader();
                return lector;

            }
            catch (SqlException)
            {
                return null;
            }
            catch (Exception)
            {
                return null;
            }


        }


        #endregion Buscar Data


        #region Ejecutar Query

        /// <summary>
        /// Metodo que recibe se encargar de invocar a los stored
        /// procedures y devolver el 1 si se realizo correctamente.
        /// </summary>>

        public int EjecutarQuery(Conexion conexion, String nombreProcedure, List<String> variablesProcedure, List<String> valoresVariables)
        {


            SqlCommand comando = new SqlCommand();

            try
            {
                //se abre una conexion a base de datos
                conexion.AbrirConexionBd();
                //se completa el objeto comando, con la informacion de la conexion , variables, y nombre del stored procedure
                comando.Connection = conexion.ObjetoConexion();
                comando.CommandType = System.Data.CommandType.StoredProcedure;
                comando.CommandText = nombreProcedure;
                comando.CommandTimeout = 10;
                //variables del stored procedure de sql server
                int i = 0;
                while (i < variablesProcedure.Count())
                {

                    comando.Parameters.AddWithValue(variablesProcedure.ElementAt(i), valoresVariables.ElementAt(i));
                    comando.Parameters[variablesProcedure.ElementAt(i)].Direction = ParameterDirection.Input;

                    i++;
                }
                //se ejecuta el comando
                return int.Parse(comando.ExecuteScalar().ToString());


            }
            catch (SqlException)
            {
                return -1;
            }
            catch (Exception)
            {
                return -1;
            }


        }


        #endregion Ejecutar Query


        #endregion Metodos Definitivos



        #region metodos en proceso de modificacion (estan porque se usan en otras clases)



        public List<Materia> ConsultarTodasLasMaterias()
        {
            List<Materia> lista = new List<Materia>();

            SqlCommand command = new SqlCommand();

            conex.AbrirConexionBd();
            command.Connection = conex.ObjetoConexion();
            command.CommandType = System.Data.CommandType.Text;
            command.CommandText = "SELECT * FROM MATERIA";
            command.CommandTimeout = 10;

            SqlDataReader reader = command.ExecuteReader();

            while (reader.Read())
            {
                // ver quizas se puede caer aqui por si hay alguna mala asignacion con los getint32
                Materia mat = new Materia();
                mat.Codigo = reader.GetInt32(0);
                mat.Descripcion = reader["descripcion"].ToString();
                mat.Nombre = reader["nombreMateria"].ToString();
                mat.HorasTeoria = reader.GetInt32(2);
                mat.HorasPractica = reader.GetInt32(3);
                mat.Estatus = reader["statusMateria"].ToString();

                lista.Add(mat);
            }
            reader.Close();
            conex.CerrarConexionBd();
            if (lista.ElementAt(0).Nombre == null)
            {
                return null;
            }
            else
                return lista;
        }

        public Materia ConsultarMateria(String codigo, int tipoConsulta)
        {
            Materia materia = new Materia();
            SqlCommand command = new SqlCommand();
            command.Connection = conex.ObjetoConexion();
            command.CommandType = System.Data.CommandType.Text;
            if (tipoConsulta == 1)
                command.CommandText = "SELECT * FROM MATERIA M WHERE M.nombreMateria = '" + codigo + "'";
            else if (tipoConsulta == 2)
                command.CommandText = "SELECT * FROM MATERIA M WHERE M.id_Materia = " + codigo;
            else
                return null;
            command.CommandTimeout = 10;
            try
            {
                conex.AbrirConexionBd();
                SqlDataReader reader = command.ExecuteReader();
                while (reader.Read())
                {
                    // ver quizas se puede caer aqui por si hay alguna mala asignacion con los getint32
                    Materia materiaConsultada = new Materia();
                    materiaConsultada.Codigo = reader.GetInt32(0);
                    materiaConsultada.Descripcion = reader["descripcion"].ToString();
                    materiaConsultada.Nombre = reader["nombreMateria"].ToString();
                    materiaConsultada.HorasTeoria = reader.GetInt32(2);
                    materiaConsultada.HorasPractica = reader.GetInt32(3);
                    materiaConsultada.Estatus = reader["statusMateria"].ToString();
                    materia = materiaConsultada;
                }
                reader.Close();
                if (materia.Nombre == null)
                    return null;
                else
                    return materia;
            }
            catch (SqlException)
            {
                return null;
            }
            catch (Exception)
            {
                return null;
            }
            finally
            {
                conex.CerrarConexionBd();
            }
        }


        public int EliminarMateria(Materia materia)
        {
            SqlCommand comando = new SqlCommand();
            String sql = "DELETE FROM MATERIA WHERE ID_MATERIA = " + materia.Codigo;
            comando.CommandText = sql;
            comando.Connection = conex.ObjetoConexion();
            try
            {
                conex.AbrirConexionBd();
                comando.ExecuteNonQuery();
                return 1;
            }
            catch (SqlException)
            {
                List<SeccionMateria> seccion = new SqlServerSeccionMateria().ConsultarSeccionesDeUnaMateria(materia);
                if (seccion != null)
                {
                    return 2;
                }
                else
                    return 0;
            }
            catch (Exception)
            {
                return 0;
            }
            finally
            {
                conex.CerrarConexionBd();
            }
        }

        public bool ModificarMateria(List<String[]> campos, Materia materia)
        {
            SqlCommand comando = new SqlCommand();
            String sql = null;
            bool estatusModificacion = false;
            foreach (String[] c in campos)
            {
                String campo = c[1];
                String valor = c[2];
                if (campo.Contains("Nombre"))
                {
                    sql = "update materia set nombreMateria = '" + valor + "' where id_Materia = " + materia.Codigo;
                }
                else if (campo.Contains("Teoria"))
                {
                    sql = "update materia set horasTeoria = " + valor + " where id_Materia = " + materia.Codigo;
                }
                else if (campo.Contains("Practica"))
                {
                    sql = "update materia set horasPractica = " + valor + " where id_Materia = " + materia.Codigo;
                }
                else if (campo.Contains("Descripcion"))
                {
                    sql = "update materia set descripcion = '" + valor + "' where id_Materia = " + materia.Codigo;
                }
                else if (campo.Contains("Estatus"))
                {
                    sql = "update materia set statusMateria = '" + valor + "' where id_Materia = " + materia.Codigo;
                }
                if (sql == null)
                {
                    estatusModificacion = false;
                }
                else
                {
                    comando.CommandText = sql;
                    comando.Connection = conex.ObjetoConexion();
                    try
                    {
                        conex.AbrirConexionBd();
                        comando.ExecuteNonQuery();
                        estatusModificacion = true;
                    }
                    catch (SqlException)
                    {
                        estatusModificacion = false;
                    }
                    catch (Exception)
                    {
                        estatusModificacion = false;
                    }
                    finally
                    {
                        conex.CerrarConexionBd();
                    }
                }
                if (estatusModificacion == false)
                {
                    return estatusModificacion;
                }
            }
            return estatusModificacion;
        }

        #endregion  metodos en proceso de modificacion (estan porque se usan en otras clases)


        #region metodo Grupo 3:Consultar Materias Por Escuela

        public List<Materia> ConsultarMateriasPorEscuela(int idEscuela)
        {
            SqlCommand command = new SqlCommand();
            List<Materia> lista = new List<Materia>();
            Conexion miConexion = new Conexion();
            try
            {
                miConexion.AbrirConexionBd();
                command.Connection = miConexion.ObjetoConexion();
                command.CommandType = System.Data.CommandType.StoredProcedure;
                command.CommandText = "[dbo].[SeleccionarMateriasPorEscuela]";
                command.CommandTimeout = 10;
                command.Parameters.AddWithValue("@idEscuela", idEscuela);
                SqlDataReader reader = command.ExecuteReader();

                while (reader.Read())
                {
                    Materia mat = new Materia();
                    mat.Codigo = reader.GetInt32(0);
                    mat.Nombre = reader["nombreMateria"].ToString();
                    mat.NumeroCreditos = reader.GetInt32(2);
                    lista.Add(mat);
                }
                reader.Close();
            }
            catch (Exception)
            {

            }
            finally
            {
                miConexion.CerrarConexionBd();
            }

            return lista;
        }
        #endregion

        #region metodo Grupo 9:Consultar HorarioEImpimirMaterias

        public String ConsultaEscuelaDeMateria(String Materia)
        {
            //se instancia un objeto de tipo conexion y sqlCommand
            //estos se utilizan para acceder a base de datos y ejecutar el stored procedure en sql server
            Conexion miConexion = new Conexion();
            SqlCommand command = new SqlCommand();
            SqlDataReader reader = null;
            try
            {
                //se abre una conexion a base de datos
                miConexion.AbrirConexionBd();
                // se completa el objeto comando, con la informacion de la conexion , variables, y nombre del stored procedure.
                command.Connection = miConexion.ObjetoConexion();
                command.CommandType = System.Data.CommandType.StoredProcedure;
                command.CommandText = "[dbo].[ConsultaEscuelaDeMateria]";
                command.CommandTimeout = 10;

                //variables del stored procedure de sql server.

                command.Parameters.AddWithValue("@NombreMateria", Materia);
                command.Parameters["@NombreMateria"].Direction = ParameterDirection.Input;

                //se ejecuta el comando
                //se carga la informacion consultada en un objeto de tipo Evaluacion
                String LaEscuela = "";


                reader = command.ExecuteReader();
                while (reader.Read())
                {
                    LaEscuela = reader.GetString(0);

                }


                return LaEscuela;
            }
            catch (SqlException)
            {
                return null;
            }
            catch (Exception e)
            {
                System.Console.WriteLine(e.StackTrace);
                System.Console.ReadLine();
                return null;
            }
            //se cierra la conexion independientemente de que se haya detectado o no una excepcion.
            finally
            {
                if (reader != null)
                    reader.Close();
                miConexion.CerrarConexionBd();
            }

        }

        public String ConsultaUniversidadDeMateria(String NombreMateria)
        {
            //se instancia un objeto de tipo conexion y sqlCommand
            //estos se utilizan para acceder a base de datos y ejecutar el stored procedure en sql server
            Conexion miConexion = new Conexion();
            SqlCommand command = new SqlCommand();
            SqlDataReader reader = null;
            try
            {
                //se abre una conexion a base de datos
                miConexion.AbrirConexionBd();
                // se completa el objeto comando, con la informacion de la conexion , variables, y nombre del stored procedure.
                command.Connection = miConexion.ObjetoConexion();
                command.CommandType = System.Data.CommandType.StoredProcedure;
                command.CommandText = "[dbo].[ConsultaUniversidadDeMateria]";
                command.CommandTimeout = 10;

                //variables del stored procedure de sql server.

                command.Parameters.AddWithValue("@NombreMateria", NombreMateria);
                command.Parameters["@NombreMateria"].Direction = ParameterDirection.Input;

                //se ejecuta el comando
                //se carga la informacion consultada en un objeto de tipo Evaluacion
                String LaEscuela = "";


                reader = command.ExecuteReader();
                while (reader.Read())
                {
                    LaEscuela = reader.GetString(0);

                }


                return LaEscuela;
            }
            catch (SqlException)
            {
                return null;
            }
            catch (Exception e)
            {
                System.Console.WriteLine(e.StackTrace);
                System.Console.ReadLine();
                return null;
            }
            //se cierra la conexion independientemente de que se haya detectado o no una excepcion.
            finally
            {
                if (reader != null)
                    reader.Close();
                miConexion.CerrarConexionBd();
            }

        }


        public List<String> ConsultarEscuelaUniversidad(int idPractica)
        {
            //se instancia un objeto de tipo conexion y sqlCommand
            //estos se utilizan para acceder a base de datos y ejecutar el stored procedure en sql server
            Conexion miConexion = new Conexion();
            SqlCommand command = new SqlCommand();
            SqlDataReader reader = null;
            try
            {
                //se abre una conexion a base de datos
                miConexion.AbrirConexionBd();
                // se completa el objeto comando, con la informacion de la conexion , variables, y nombre del stored procedure.
                command.Connection = miConexion.ObjetoConexion();
                command.CommandType = System.Data.CommandType.StoredProcedure;
                command.CommandText = "[dbo].[ConsultarEscuelaUniversidad]";
                command.CommandTimeout = 10;

                //variables del stored procedure de sql server.

                command.Parameters.AddWithValue("@idPractica", idPractica);
                command.Parameters["@idPractica"].Direction = ParameterDirection.Input;

                //se ejecuta el comando
                //se carga la informacion consultada en un objeto de tipo Evaluacion
                List<String> datos = new List<String>();


                reader = command.ExecuteReader();
                while (reader.Read())
                {
                    datos.Insert(0, reader.GetString(0));
                    datos.Insert(1, reader.GetString(1));
                }


                return datos;
            }
            catch (SqlException)
            {
                return null;
            }
            catch (Exception e)
            {
                System.Console.WriteLine(e.StackTrace);
                System.Console.ReadLine();
                return null;
            }
            //se cierra la conexion independientemente de que se haya detectado o no una excepcion.
            finally
            {
                if (reader != null)
                    reader.Close();
                miConexion.CerrarConexionBd();
            }

        }

        #endregion

        /// <summary>
        /// Metodo que consulta todas las materias de un profesor en el periodo academico actual
        /// </summary>
        /// <param name="profesor"></param>
        /// <returns></returns>
        public List<SeccionMateria> ConsultarMateriaProfesorPeriodo(Profesor profesor)
        {
            List<SeccionMateria> retorno = new List<SeccionMateria>();
            SqlCommand command = new SqlCommand();
            try
            {
                conex.AbrirConexionBd();
                command.Connection = conex.ObjetoConexion();
                command.CommandType = System.Data.CommandType.StoredProcedure;
                command.CommandText = "[dbo].[ConsultarListaMateriasProfesorPeriodoAcademico]"; // nombre del storedProcedure
                command.CommandTimeout = 10;
                command.Parameters.AddWithValue("@cedula", profesor.Cedula);

                SqlDataReader reader = command.ExecuteReader();

                while (reader.Read())
                {
                    SeccionMateria seccionMateria = new SeccionMateria();

                    seccionMateria.Materia = new Materia();
                    seccionMateria.Materia.Codigo = reader.GetInt32(0);
                    seccionMateria.Materia.Nombre = reader.GetString(1);
                    seccionMateria.IdSeccionMateria = reader.GetInt32(2);
                    seccionMateria.Codigo = reader.GetInt32(3);
                    retorno.Add(seccionMateria);
                }
                reader.Close();
            }
            catch (SqlException)
            {
            }
            catch (NullReferenceException)
            {
            }
            catch (Exception)
            {
            }
            finally
            {
                conex.CerrarConexionBd();
            }
            return retorno;
        }

        /// <summary>
        /// Metodo que consulta todas las materias de un alumno en el periodo academico actual
        /// </summary>
        /// <param name="estudiante"></param>
        /// <returns></returns>
        public List<SeccionMateria> ConsultarMateriaEstudiantePeriodo(Estudiante estudiante)
        {
            List<SeccionMateria> retorno = new List<SeccionMateria>();
            SqlCommand command = new SqlCommand();
            try
            {
                conex.AbrirConexionBd();
                command.Connection = conex.ObjetoConexion();
                command.CommandType = System.Data.CommandType.StoredProcedure;
                command.CommandText = "[dbo].[ConsultarListaMateriasAlumnoPeriodoAcademico]"; // nombre del storedProcedure
                command.CommandTimeout = 10;
                command.Parameters.AddWithValue("@idEstudiante", estudiante.IdEst);

                SqlDataReader reader = command.ExecuteReader();

                while (reader.Read())
                {
                    SeccionMateria seccionMateria = new SeccionMateria();

                    seccionMateria.Materia = new Materia();
                    seccionMateria.Materia.Codigo = reader.GetInt32(0);
                    seccionMateria.Materia.Nombre = reader.GetString(1);
                    seccionMateria.IdSeccionMateria = reader.GetInt32(2);
                    seccionMateria.Codigo = reader.GetInt32(3);
                    retorno.Add(seccionMateria);
                }
                reader.Close();
            }
            catch (SqlException)
            {
            }
            catch (NullReferenceException)
            {
            }
            catch (Exception)
            {
            }
            finally
            {
                conex.CerrarConexionBd();
            }
            return retorno;
        }

        /// <summary>
        /// Metodo que consulta todas las materias de una escuela en el periodo academico actual
        /// </summary>
        /// <param name="escuela"></param>
        /// <returns></returns>
        public List<SeccionMateria> ConsultarMateriaEscuelaPeriodo(Escuela escuela)
        {
            List<SeccionMateria> retorno = new List<SeccionMateria>();
            SqlCommand command = new SqlCommand();
            try
            {
                conex.AbrirConexionBd();
                command.Connection = conex.ObjetoConexion();
                command.CommandType = System.Data.CommandType.StoredProcedure;
                command.CommandText = "[dbo].[ConsultarListaMateriasEscuelaPeriodoAcademico]"; // nombre del storedProcedure
                command.CommandTimeout = 10;
                command.Parameters.AddWithValue("@idEscuela", escuela.IdEscuela);

                SqlDataReader reader = command.ExecuteReader();

                while (reader.Read())
                {
                    SeccionMateria seccionMateria = new SeccionMateria();

                    seccionMateria.Materia = new Materia();
                    seccionMateria.Materia.Codigo = reader.GetInt32(0);
                    seccionMateria.Materia.Nombre = reader.GetString(1);
                    seccionMateria.IdSeccionMateria = reader.GetInt32(2);
                    seccionMateria.Codigo = reader.GetInt32(3);
                    retorno.Add(seccionMateria);
                }
                reader.Close();
            }
            catch (SqlException)
            {
            }
            catch (NullReferenceException)
            {
            }
            catch (Exception)
            {
            }
            finally
            {
                conex.CerrarConexionBd();
            }
            return retorno;
        }
    }
}